package com.jilujia.domain.blog.service;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.jilujia.domain.blog.Blog;
import com.jilujia.domain.blog.BlogCatalog;
import com.jilujia.domain.blog.BlogComment;
import com.jilujia.domain.blog.BlogCommentManager;
import com.jilujia.domain.blog.BlogManager;
import com.jilujia.domain.blog.repository.BlogCatalogRepository;
import com.jilujia.domain.blog.repository.BlogCommentRepository;
import com.jilujia.domain.blog.repository.BlogRepository;
import com.jilujia.domain.region.Region;
import com.jilujia.framework.domain.AbstractService;
import com.jilujia.framework.exception.BusinessException;

/**
 * A JPA-based implementation of the Booking Service. Delegates to a JPA entity
 * manager to issue data access calls against the backing repository. The
 * EntityManager reference is provided by the managing container (Spring)
 * automatically.
 */
@Service("blogService")
@Transactional(readOnly = true)
public class BlogServiceImpl extends AbstractService implements BlogService {

	private static final Logger LOG = LoggerFactory.getLogger(BlogServiceImpl.class);

	@Autowired
	private BlogRepository blogRepository;

	@Autowired
	private BlogCommentRepository blogCommentRepository;

	@Autowired
	private BlogCatalogRepository blogCatalogRepository;

	public Blog createNewBlog() {
		Blog blog = new Blog();

		return blog;
	}

	public List<BlogCatalog> findCatalogList(Long userId) {
		return blogCatalogRepository.findCatalogsByUserId(userId);
	}

	@Transactional
	public Blog persistBlog(Blog blogVo, Long userId, boolean isDraft) {
		// 完整从界面来的VO属性，catalog、asDraft（注意userId不是由界面决定的）
		BlogCatalog catalog = blogCatalogRepository.findOne(blogVo.getCatalog().getId());
		blogVo.setCatalog(catalog);

		if (userId.longValue() != catalog.getUserId().longValue()) {
			throw new BusinessException("user:" + blogVo.getUserId() + " access the catalog:" + catalog.getId());
		}

		blogVo.setAsDraft(isDraft);

		// 初始化PO
		Blog blogPo = new Blog();

		// 是否第一次发布
		boolean firstPostFlag = false;

		if (blogVo.getId() == null) {
			// new Blog
			blogPo.setCreatedDate(new Date(System.currentTimeMillis()));
			blogPo.setModifyDate(new Date(System.currentTimeMillis()));
			blogPo.setUserId(userId);

			// 直接发布
			if (!isDraft) {
				firstPostFlag = true;
			}
		} else {
			// edit blog
			blogPo = blogRepository.findOne(blogVo.getId());

			// 当前user和blog本身的user不一致，抛错
			if (userId.longValue() != blogPo.getUserId().longValue()) {
				throw new BusinessException("operate wrong blog!");
			}

			// blog已经发布过，不能再变成draft
			if (!blogPo.getAsDraft() && isDraft) {
				throw new BusinessException("can't turn posted blog to draft");
			}

			// 把Draft发布
			if (blogPo.getAsDraft() && !isDraft) {
				firstPostFlag = true;
			}

			blogPo.setModifyDate(new Date(System.currentTimeMillis()));
			blogPo.setModifierId(userId);
		}

		// 把VO属性copy到PO上
		blogPo.processVo(blogVo);

		// 之前所有的动作都是为了生成完整的PO

		BlogManager blogManager = getApplicationContext().getBean(BlogManager.class);
		blogManager.setInstance(blogPo);
		blogManager.saveBlog(firstPostFlag);
		blogPo = blogManager.getInstance();

		return blogPo;
	}

	public Blog findBlog(Long blogId) {
		return blogRepository.findOne(blogId);
	}

	public List<Blog> findBlogList(Long userId) {
		return blogRepository.findBlogsByUserId(userId);
	}

	public List<BlogComment> findBlogCommentList(Long blogId) {
		return blogCommentRepository.findBlogCommentListByBlogId(blogId);
	}

	public BlogComment createNewBlogComment(Blog blog) {
		BlogComment blogComment = new BlogComment();
		blogComment.setBlog(blog);
		return blogComment;
	}

	@Transactional
	public BlogComment persistBlogComment(BlogComment blogCommentVo, Long userId) {

		BlogCommentManager blogCommentManager = getApplicationContext().getBean(BlogCommentManager.class);
		BlogComment blogCommentPo = blogCommentManager.saveBlogComment(blogCommentVo, userId);

		// blog replycount + 1
		BlogManager blogManager = getApplicationContext().getBean(BlogManager.class);
		blogManager.setInstance(blogCommentPo.getBlog());
		blogManager.addReplyCount();

		return blogCommentPo;
	}

	public List<Blog> findTop10BlogsByRegion(Region region) {
		// TODO region和blog的关联还没做。
		return blogRepository.findAll();
	}

	public List<Blog> findAllBlogList() {
		return blogRepository.findAll();
	}

}